﻿using System;
using System.Collections.Generic;
using System.Device.Location;
using System.Diagnostics;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Input;
using System.Windows.Shapes;
using System.Linq;
using BootyShaker.Utils;
using System.Windows.Controls.Primitives;

namespace BootyShaker
{
    public partial class ShakeDesigner : UserControl
    {
        Action returnMethod;

        public ApplicationBar ApplicationBar;
        ApplicationBarIconButton btnReset;
        ApplicationBarIconButton btnAdd;
        ApplicationBarIconButton btnDone;
        ApplicationBarIconButton btnSave;

        public ShakeDesigner(Action returnMeth)
        {
            InitializeComponent();
            returnMethod = returnMeth;

            ApplicationBar = new ApplicationBar();

            btnReset = new ApplicationBarIconButton();
            btnReset.IconUri = new Uri("/Icons/appbar.reset.rest.png", UriKind.Relative);
            btnReset.Text = "Reset";
            btnReset.Click += btnReset_Click;
            ApplicationBar.Buttons.Add(btnReset);

            btnAdd = new ApplicationBarIconButton();
            btnAdd.IconUri = new Uri("/Icons/appbar.add.rest.png", UriKind.Relative);
            btnAdd.Text = "Reset";
            btnAdd.Click += btnAdd_Click;
            ApplicationBar.Buttons.Add(btnAdd);

            btnDone = new ApplicationBarIconButton();
            btnDone.IconUri = new Uri("/Icons/appbar.play.rest.png", UriKind.Relative);
            btnDone.Text = "Done";
            btnDone.Click += btnAccept_Click;
            ApplicationBar.Buttons.Add(btnDone);

            btnSave = new ApplicationBarIconButton();
            btnSave.IconUri = new Uri("/Icons/appbar.save.rest.png", UriKind.Relative);
            btnSave.Text = "Save";
            btnSave.Click += btnSave_Click;
            ApplicationBar.Buttons.Add(btnSave);
            //<shell:ApplicationBarIconButton x:Name="btnReset" IsEnabled="false" IconUri="/Icons/appbar.reset.rest.png" Text="Reset"  Click="btnReset_Click"/>
            //<shell:ApplicationBarIconButton x:Name="btnAdd" IsEnabled="false" IconUri="/Icons/appbar.add.rest.png" Text="Add" Click="btnAdd_Click" />
            //<shell:ApplicationBarIconButton x:Name="btnDone" IsEnabled="false" IconUri="/Icons/appbar.play.rest.png" Text="Done" Click="btnAccept_Click" />
            //<shell:ApplicationBarIconButton x:Name="btnSave" IsEnabled="false" IconUri="/Icons/appbar.save.rest.png" Text="Save" Click="btnSave_Click" />

              //<shell:ApplicationBarMenuItem Text="Save" IsEnabled="false" Click="ApplicationBarMenuItem_Click_1"></shell:ApplicationBarMenuItem>
              //<shell:ApplicationBarMenuItem Text="Save As" IsEnabled="false" Click="ApplicationBarMenuItem_Click_3"></shell:ApplicationBarMenuItem>
              //<shell:ApplicationBarMenuItem Text="Settings" IsEnabled="false" Click="ApplicationBarMenuItem_Click_2"></shell:ApplicationBarMenuItem>
              //<shell:ApplicationBarMenuItem Text="Help" IsEnabled="false" Click="ApplicationBarMenuItem_Click"></shell:ApplicationBarMenuItem>
            ApplicationBarMenuItem menuItem = new ApplicationBarMenuItem();
            menuItem.Text = "Save";
            menuItem.Click += ApplicationBarMenuItem_Click_1;
            ApplicationBar.MenuItems.Add(menuItem);

            menuItem = new ApplicationBarMenuItem();
            menuItem.Text = "Save As";
            menuItem.Click += ApplicationBarMenuItem_Click_3;
            ApplicationBar.MenuItems.Add(menuItem);

            menuItem = new ApplicationBarMenuItem();
            menuItem.Text = "Settings";
            menuItem.Click += ApplicationBarMenuItem_Click_2;
            ApplicationBar.MenuItems.Add(menuItem);

            menuItem = new ApplicationBarMenuItem();
            menuItem.Text = "Help";
            menuItem.Click += ApplicationBarMenuItem_Click;
            ApplicationBar.MenuItems.Add(menuItem);
            
            App.shakeObjects = new List<ShakeObjectCtl>();

            canvas.Opacity = 0;

        }
        void AdRotatorControl_Log(string message)
        {
            Debug.WriteLine(message);
        }

        //void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
        //{
        //    IsolatedStorageSettings.ApplicationSettings.Add("GPSLocation", e.Position.Location);
        //    IsolatedStorageSettings.ApplicationSettings.Save();
        //    //myAdControl.Latitude = e.Position.Location.Latitude;
        //    //myAdControl.Longitude = e.Position.Location.Longitude;

        //}

        public void GoBack()
        {
            Hide.Begin();
            returnMethod();
        }



        private void fitImage()
        {


            GeneralTransform gt = Application.Current.RootVisual.TransformToVisual(canvas);
            scaleTransform.CenterX = scaleTransform.CenterY = 0;
            rotateTransform.CenterX = rotateTransform.CenterY = 0;

            double MinScale = Math.Max(Application.Current.RootVisual.RenderSize.Width / App.currentShaker.shakeImage.PixelWidth,
                          Application.Current.RootVisual.RenderSize.Height / App.currentShaker.shakeImage.PixelHeight);

            scaleTransform.ScaleX = 1;
            scaleTransform.ScaleY = 1;

            rotateTransform.Angle = 0;

            translateTransform.X = gt.Transform(new Point(0, 0)).X;
            translateTransform.Y = gt.Transform(new Point(0, 0)).Y;
            previousTransform.Matrix = new Matrix(MinScale, 0, 0, MinScale, 0, 0);
            //TransferTransforms();
        }


        //private void OnTap(object sender, GestureEventArgs e)
        //{
        //    //imgTransform.TranslateX = imgTransform.TranslateY = 0;
        //    //e.Handled = true;
        //}

        //private void OnDoubleTap(object sender, GestureEventArgs e)
        //{
        //    //imgTransform.ScaleX = imgTransform.ScaleY = 1;
        //    //e.Handled = true;
        //}

        //private void OnHold(object sender, GestureEventArgs e)
        //{
        //    //imgTransform.TranslateX = imgTransform.TranslateY = 0;
        //    //imgTransform.ScaleX = imgTransform.ScaleY = 1;
        //    //imgTransform.Rotation = 0;
        //    //e.Handled = true;
        //}
        //private void shakeImage_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
        //{

        //    initialScale = imgTransform.ScaleY;

        //}

        //private void shakeImage_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
        //{
        //    //this.imgTransform.TranslateX += e.DeltaManipulation.Translation.X;
        //    //this.imgTransform.TranslateY += e.DeltaManipulation.Translation.Y;
        //    ////Distance(e, Point B)
        //    //if (Math.Min(e.DeltaManipulation.Scale.X, e.DeltaManipulation.Scale.Y) != 0)
        //    //{
        //    //    imgTransform.ScaleX = imgTransform.ScaleY = initialScale * Math.Max(e.CumulativeManipulation.Scale.X, e.CumulativeManipulation.Scale.Y);

        //    //    //this.imgTransform.ScaleX = e.DeltaManipulation.Scale.X;
        //    //    //this.imgTransform.ScaleY = e.DeltaManipulation.Scale.Y;
        //    //}
        //}
        bool drag = false;

        private double initialAngle;
        private double initialScale;
        private Point initialTPLocation;
        private Point previousTPLocation;
        private Point initialTP1Location;
        private Point initialTP2Location;
        bool scale = false;
        void Touch_FrameReported(object sender, System.Windows.Input.TouchFrameEventArgs e)
        {
            if (!LayoutRoot.IsHitTestVisible) return;

            System.Windows.Input.TouchPointCollection tpc = e.GetTouchPoints(Application.Current.RootVisual);
            bool handled = false;
            for (int i = App.shakeObjects.Count - 1; i >= 0; i--)
            //foreach (ShakeObjectCtl obj in App.shakeObjects)
            {
                handled = App.shakeObjects[i].Touch_FrameReported(sender, e) || handled;
                if (handled) break;
            }
            if (handled) return;



            if (tpc.Count == 1)
            {
                TouchPoint tp = tpc[0];

                if (tp.Action == TouchAction.Down && !drag && Util.intersects(Util.ControlBounds(shakeImage), Application.Current.RootVisual.TransformToVisual(shakeImage).Transform(tp.Position)))
                {
                    //Point center = shakeImage.TransformToVisual(Application.Current.RootVisual).Inverse.Transform(tp.Position);

                    initialTPLocation = tp.Position;
                    previousTPLocation = tp.Position;
                    drag = true;

                }
                else if (tp.Action == TouchAction.Move && drag)
                {
                    //Canvas.SetLeft(shakeImage,Canvas.GetLeft(shakeImage) + tp.Position.X - initiallocation.X);
                    //Canvas.SetTop(shakeImage, Canvas.GetTop(shakeImage) + tp.Position.Y - initiallocation.Y);

                    translateTransform.X += tp.Position.X - previousTPLocation.X;
                    translateTransform.Y += tp.Position.Y - previousTPLocation.Y;
                    previousTPLocation = tp.Position;

                }
                else if (tp.Action == TouchAction.Up && drag)
                {
                    TransferTransforms();
                    drag = false;

                }
            }
            else if (tpc.Count == 2)
            {
                TouchPoint tp1 = tpc[0];
                TouchPoint tp2 = tpc[1];
                drag = false;
                if ((tp1.Action == TouchAction.Down || tp2.Action == TouchAction.Down) && Util.intersects(Util.ControlBounds(shakeImage), Application.Current.RootVisual.TransformToVisual(shakeImage).Transform(tp1.Position)) && Util.intersects(Util.ControlBounds(shakeImage), Application.Current.RootVisual.TransformToVisual(shakeImage).Transform(tp2.Position)))
                {
                    initialTP1Location = tp1.Position;
                    initialTP2Location = tp2.Position;
                    initialScale = scaleTransform.ScaleY;

                    initialAngle = rotateTransform.Angle;
                    // Point center = Application.Current.RootVisual.TransformToVisual(shakeImage).Transform(Util.Center(initialTP2Location, initialTP1Location));
                    //Point center = shakeImage.TransformToVisual(Application.Current.RootVisual).Inverse.Transform(Util.Center(initialTP2Location, initialTP1Location));
                    //imgTransform.CenterX = center.X;
                    //imgTransform.CenterY = center.Y;
                    Point center = Util.Center(e.GetTouchPoints(shakeImage)[0].Position, e.GetTouchPoints(shakeImage)[1].Position);
                    center = previousTransform.Transform(center);

                    scaleTransform.CenterX = rotateTransform.CenterX = center.X;
                    scaleTransform.CenterY = rotateTransform.CenterY = center.Y;

                    scale = true;

                }
                else if ((tp1.Action == TouchAction.Move || tp2.Action == TouchAction.Move) && (tp1.Action != TouchAction.Up && tp2.Action != TouchAction.Up) && scale)
                {

                    Util.Distance(tp1.Position, tp2.Position);
                    Util.Distance(initialTP1Location, initialTP2Location);

                    double newscale = initialScale * Util.Distance(tp1.Position, tp2.Position) / Util.Distance(initialTP1Location, initialTP2Location);

                    //if (this.ActualWidth * newscale * previousTransform.Matrix.M11 < this.MaxWidth && this.ActualWidth * newscale * previousTransform.Matrix.M11 > this.MinWidth && this.ActualHeight * newscale * previousTransform.Matrix.M22 < this.MaxHeight && this.ActualHeight * newscale * previousTransform.Matrix.M22 > this.MinHeight)
                    //{
                    scaleTransform.ScaleX = scaleTransform.ScaleY = newscale;
                    //}
                    rotateTransform.Angle = initialAngle + Util.angle(initialTP1Location, initialTP2Location) - Util.angle(tp1.Position, tp2.Position);

                }
                else if ((tp1.Action == TouchAction.Up || tp2.Action == TouchAction.Up) && scale)
                {
                    TransferTransforms();
                    scale = false;

                }
            }

        }
        void TransferTransforms()
        {
            previousTransform.Matrix = Multiply(previousTransform.Matrix, currentTransform.Value);

            // Set current transforms to default values
            scaleTransform.ScaleX = scaleTransform.ScaleY = 1;
            scaleTransform.CenterX = scaleTransform.CenterY = 0;

            rotateTransform.Angle = 0;
            rotateTransform.CenterX = rotateTransform.CenterY = 0;

            translateTransform.X = translateTransform.Y = 0;
        }

        Matrix Multiply(Matrix A, Matrix B)
        {
            return new Matrix(A.M11 * B.M11 + A.M12 * B.M21,
                              A.M11 * B.M12 + A.M12 * B.M22,
                              A.M21 * B.M11 + A.M22 * B.M21,
                              A.M21 * B.M12 + A.M22 * B.M22,
                              A.OffsetX * B.M11 + A.OffsetY * B.M21 + B.OffsetX,
                              A.OffsetX * B.M12 + A.OffsetY * B.M22 + B.OffsetY);
        }

        //private void shakeImage_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
        //{

        //}

        //private void OnDragStarted(object sender, DragStartedGestureEventArgs e)
        //{
        //    // border.Background = greenBrush;
        //    e.Handled = true;
        //}

        //private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
        //{
        //    imgTransform.TranslateX += e.HorizontalChange;
        //    imgTransform.TranslateY += e.VerticalChange;
        //    e.Handled = true;
        //}

        //private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
        //{
        //    // border.Background = normalBrush;
        //    e.Handled = true;
        //}

        //private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
        //{
        //    //border.Background = redBrush;
        //    imgTransform.CenterX = (e.GetPosition((UIElement)e.OriginalSource, 0).X + e.GetPosition((UIElement)e.OriginalSource, 1).X) / 2;
        //    imgTransform.CenterY = (e.GetPosition((UIElement)e.OriginalSource, 0).Y + e.GetPosition((UIElement)e.OriginalSource, 1).Y) / 2;
        //    initialAngle = imgTransform.Rotation;
        //    initialScale = imgTransform.ScaleX;

        //    e.Handled = true;
        //}

        //private void OnPinchDelta(object sender, PinchGestureEventArgs e)
        //{
        //    imgTransform.Rotation = initialAngle + e.TotalAngleDelta;
        //    imgTransform.ScaleX = imgTransform.ScaleY = initialScale * e.DistanceRatio;

        //    e.Handled = true;

        //}

        //private void OnPinchCompleted(object sender, PinchGestureEventArgs e)
        //{
        //    //border.Background = normalBrush;
        //    e.Handled = true;
        //}

        //private void OnFlick(object sender, FlickGestureEventArgs e)
        //{
        //    // flickData.Text = string.Format("{0} Flick: Angle {1} Velocity {2},{3}",
        //    //  e.Direction, Math.Round(e.Angle), e.HorizontalVelocity, e.VerticalVelocity);
        //    e.Handled = true;
        //}


        double InitialSize = 200;
        private void btnAdd_Click(object sender, EventArgs e)
        {
            UIAddObject();

        }
        private void UIAddObject()
        {
            Point p = new Point(150, 150);
            UIAddObject(p);
        }
        private void UIAddObject(Point p)
        {
            if (App.IsTrial && App.shakeObjects.Count >= 2)
            {
                if (MessageBox.Show("Whoa! Two is enough already, stud. Not enough? Well with the full version you can add as many as you want;)! Go buy now?", "Trial version", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    if (popup != null)
                        popup.IsOpen = false;
                    ReleaseLayout();
                    Microsoft.Phone.Tasks.MarketplaceDetailTask marketplaceDetailTask = new Microsoft.Phone.Tasks.MarketplaceDetailTask();
                    marketplaceDetailTask.Show();
                    return;
                }
                else
                {
                    return;
                }
            }

            Size sz;
            if (App.shakeObjects.Count > 0)
            {
                ShakeObjectCtl last = App.shakeObjects.Last();
                sz = new Size(last.size.Width, last.size.Height);
            }
            else
                sz = new Size(InitialSize, InitialSize);

            p.X -= sz.Width / 2;
            p.Y -= sz.Height / 2;
            AddObject(p, sz);
        }
        private void AddObject(Point p, Size sz)
        {

            ShakeObjectCtl obj = new ShakeObjectCtl(p, sz, canvas, shakeImage, ShakeObjectDeleteCallback);
            App.shakeObjects.Add(obj);
            canvas.Children.Add(obj);
            UpdateTrialMenuButtons();
        }
        void ShakeObjectDeleteCallback()
        {
            UpdateTrialMenuButtons();
        }



        private void btnAccept_Click(object sender, EventArgs e)
        {
            //showProgresBar();
            try
            {
                // GeneralTransform gt = shakeImage.TransformToVisual(Application.Current.RootVisual);

                App.gt = canvas.TransformToVisual(Application.Current.RootVisual);
                //Point topLeft = new Point(0, 0);
                //topLeft = grpTransform.Transform(topLeft);
                //Point bottomLeft = new Point(0, shakeImage.ActualHeight);
                //bottomLeft = grpTransform.Transform(bottomLeft);
                //Point topRight = new Point(shakeImage.ActualWidth, 0);
                //topRight = grpTransform.Transform(topRight);
                //Point bottomRight = new Point(shakeImage.ActualWidth, shakeImage.ActualHeight);
                //bottomRight = grpTransform.Transform(bottomRight);

                //int minx = (int)Math.Min(Math.Min(topLeft.X, bottomLeft.X), Math.Min(topRight.X, bottomRight.X));
                //int maxx = (int)Math.Max(Math.Max(topLeft.X, bottomLeft.X), Math.Max(topRight.X, bottomRight.X));
                //int miny = (int)Math.Min(Math.Min(topLeft.Y, bottomLeft.Y), Math.Min(topRight.Y, bottomRight.Y));
                //int maxy = (int)Math.Max(Math.Max(topLeft.Y, bottomLeft.Y), Math.Max(topRight.Y, bottomRight.Y));

                //int width = maxx - minx;
                //int height = maxy - miny;

                //TransformGroup ct = (TransformGroup)shakeImage.RenderTransform;
                //CompositeTransform st = new CompositeTransform();
                //st.ScaleX = scaleTransform.ScaleX;
                //st.ScaleY = scaleTransform.ScaleY;

                //st.CenterX = shakeImage.ActualWidth / 2;// imgTransform.CenterX;
                //st.CenterY = shakeImage.ActualHeight / 2;//imgTransform.CenterY;
                //st.Rotation = rotateTransform.Angle;
                //st.TranslateX = width / 2 - shakeImage.ActualWidth / 2;
                //st.TranslateY = height / 2 - shakeImage.ActualHeight / 2;


                shakeImage.UpdateLayout();

                //App.ShakeImageTransformed = new WriteableBitmap(width, height);
                //App.ShakeImageTransformed.Render(shakeImage, st);
                App.ShakeImageTransformed = new WriteableBitmap((int)Application.Current.RootVisual.RenderSize.Width, (int)Application.Current.RootVisual.RenderSize.Height);
                App.ShakeImageTransformed.Render(shakeImage, grpTransform);

                App.ShakeImageTransformed.Invalidate();


                // SaveImage();

                //topLeft = App.gt.Transform(new Point(minx, miny));
                //App.ShakeImagePos = new Microsoft.Xna.Framework.Vector2((float)topLeft.X, (float)topLeft.Y);

                App.ShakeImagePos = new Microsoft.Xna.Framework.Vector2(0, 0);
                updateShakerState();
                ShowGamePage();
                //NavigationService.Navigate(new Uri("/GamePage.xaml", UriKind.Relative));
            }
            finally
            {
                //hideProgresBar();
            }
        }


        private void ShowGamePage()
        {
            App.NavigateTo(CurrentView.GameScreen);
        }


        private void btnReset_Click(object sender, EventArgs e)
        {
            foreach (ShakeObjectCtl obj in App.shakeObjects)
            {
                canvas.Children.Remove(obj);
            }
            App.shakeObjects.Clear();
            fitImage();
            UpdateTrialMenuButtons();
        }

        public bool doLoad = true;
        public void LoadShakeDesigner()
        {
            if (!doLoad) return;
                doLoad = false;
            //if (!LayoutRoot.IsHitTestVisible)
            //{
            //    return;
            //}
            scaleTransform.ScaleX = scaleTransform.ScaleY = 1;
            scaleTransform.CenterX = scaleTransform.CenterY = 0;

            rotateTransform.Angle = 0;
            rotateTransform.CenterX = rotateTransform.CenterY = 0;

            translateTransform.X = translateTransform.Y = 0;

            foreach (ShakeObjectCtl obj in App.shakeObjects)
            {
                canvas.Children.Remove(obj);
            }
            App.shakeObjects.Clear();

            if (App.currentShaker.isNew)
            {
                this.shakeImage.Source = App.currentShaker.shakeImage;
                fitImage();
                App.currentShaker.isNew = false;
                // doLoad = false;
            }
            if (App.currentShaker.isLoad)
            {
                this.shakeImage.Source = App.currentShaker.shakeImage;
                Canvas.SetLeft(this.shakeImage, App.currentShaker.shakeImagePosition.X);
                Canvas.SetLeft(this.shakeImage, App.currentShaker.shakeImagePosition.Y);
                Point canvasOffset = Application.Current.RootVisual.TransformToVisual(canvas).Transform(new Point(0, 0));

                previousTransform.Matrix = App.currentShaker.matrix;
                AppSettings settings = new AppSettings();
                settings.DampingRatioSetting = App.currentShaker.DampingRatio;
                settings.FrequencySetting = App.currentShaker.Frequency;
                settings.GravityRatioSetting = App.currentShaker.GravityRatio;

                settings.DragStrengthSetting = App.currentShaker.DragStrength;
                settings.MergeOverlaySetting = App.currentShaker.MergeOverlay;

                //scaleTransform.CenterX = scaleTransform.CenterY = App.currentShaker.CenterY;
                //rotateTransform.CenterX = rotateTransform.CenterY = App.currentShaker.CenterX;

                //scaleTransform.ScaleY = App.currentShaker.ScaleY;
                //scaleTransform.ScaleX = App.currentShaker.ScaleX;

                //rotateTransform.Angle = App.currentShaker.Rotation;

                //translateTransform.Y = App.currentShaker.TranslateY + canvasOffset.Y;
                //translateTransform.X = App.currentShaker.TranslateX + canvasOffset.X;

                foreach (ShakeObject obj in App.currentShaker.shakeObjects)
                {
                    AddObject(obj.location, obj.size);
                }

                App.currentShaker.isLoad = false;
            }
            ReleaseLayout();
        }

        System.Windows.Controls.Primitives.Popup popup = null;
        FileSaveDialog fs;
        private void btnSave_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void Save(bool saveAs = false)
        {

            //showProgresBar();
            try
            {
                updateShakerState();



                if (App.currentShaker.filename == null || saveAs)
                {

                    using (IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        int i = 0;
                        while (myStore.FileExists(string.Format("Untitled{0,2:D3}.shk", i)))
                        {
                            i++;
                        }

                        string filename = string.Format("Untitled{0,2:D3}", i);
                        SuspendLayout();
                        if (popup == null)
                        {
                            popup = new Popup();
                            fs = new FileSaveDialog(filename, saveCallback);

                        }
                        fs.FileName = filename;
                        popup.Child = fs;

                        popup.VerticalOffset = 25;

                        popup.HorizontalOffset = 25;

                        popup.IsOpen = true;

                    }
                }
                else
                {
                    SuspendLayout();
                    using (IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        if (myStore.FileExists(App.currentShaker.filename))
                        {
                            myStore.DeleteFile(App.currentShaker.filename);
                        }
                        IsolatedStorageFileStream myFileStream = myStore.CreateFile(App.currentShaker.filename);
                        App.currentShaker.Save(myFileStream);
                        myFileStream.Close();

                    }
                    Shaker.GetPreviewImage(App.currentShaker.filename, true);
                    MessageBox.Show("Congrats! File saved.");
                    ReleaseLayout();
                }

            }
            finally
            {
                //hideProgresBar();
            }
        }
        void saveCallback(string filename, bool cancel)
        {
            // Restore mouse function on parent page
            if (cancel)
            {
                if (popup != null)
                    popup.IsOpen = false;
                ReleaseLayout();
                return;
            }
            string[] files;
            string fn;
            using (IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                files = myStore.GetFileNames("*.shk");


                fn = string.Format("{0}.shk", filename);


                if (myStore.FileExists(fn))
                {
                    if (MessageBox.Show("File already exists. Overwrite?", "Save file", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        myStore.DeleteFile(fn);
                    }
                    else return;
                }
            }
            if (App.IsTrial && files.Length >= 3)
            {
                if (MessageBox.Show("Oops, only 3 files allowed in trial. Good news - you can buy the full version with no limitations. Go to marketplace?", "Trial version", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    if (popup != null)
                        popup.IsOpen = false;
                    ReleaseLayout();
                    Microsoft.Phone.Tasks.MarketplaceDetailTask marketplaceDetailTask = new Microsoft.Phone.Tasks.MarketplaceDetailTask();
                    marketplaceDetailTask.Show();
                    return;
                }
                else
                {

                }

            }
            else
            {
                using (IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    IsolatedStorageFileStream myFileStream = myStore.CreateFile(fn);
                    App.currentShaker.Save(myFileStream);
                    App.currentShaker.filename = fn;
                    myFileStream.Close();
                    if (popup != null)
                        popup.IsOpen = false;


                }
                Shaker.GetPreviewImage(App.currentShaker.filename, true);
                ReleaseLayout();
                MessageBox.Show("Congrats! File saved.");
            }

        }

        void UpdateTrialMenuButtons()
        {
            if (App.IsTrial)
            {
                try
                {
                    var myStore = IsolatedStorageFile.GetUserStoreForApplication();
                    string[] files = myStore.GetFileNames("*.shk");
                    ApplicationBarIconButton btn = null;
                    foreach (ApplicationBarIconButton bt in ApplicationBar.Buttons)
                    {
                        if (bt.Text == "Save")
                            btn = bt;
                    }
                    if (btn != null)
                    {
                        if (files.Length >= 3 && !App.currentShaker.isLoad)
                        {

                            btn.IconUri = new Uri("/Icons/appbar.save.trial.rest.png", UriKind.Relative);
                        }
                        else
                        {
                            btn.IconUri = new Uri("/Icons/appbar.save.rest.png", UriKind.Relative);
                        }
                    }
                    btn = null;

                    foreach (ApplicationBarIconButton bt in ApplicationBar.Buttons)
                    {
                        if (bt.Text == "Add")
                            btn = bt;
                    }
                    if (btn != null)
                    {
                        if (App.shakeObjects.Count >= 2)
                        {
                            btn.IconUri = new Uri("/Icons/appbar.add.trial.rest.png", UriKind.Relative);
                        }
                        else
                        {
                            btn.IconUri = new Uri("/Icons/appbar.add.rest.png", UriKind.Relative);
                        }
                    }
                }
                catch { }

            }
        }

        void SuspendLayout()
        {
            LayoutRoot.IsHitTestVisible = false;
            Touch.FrameReported -= new TouchFrameEventHandler(Touch_FrameReported);
            ApplicationBar.IsMenuEnabled = false;

            foreach (ApplicationBarMenuItem mnu in ApplicationBar.MenuItems)
            {
                mnu.IsEnabled = false;
            }
            foreach (ApplicationBarIconButton btn in ApplicationBar.Buttons)
            {
                btn.IsEnabled = false;
            }
        }
        void ReleaseLayout()
        {
            LayoutRoot.IsHitTestVisible = true;
            Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
            ApplicationBar.IsMenuEnabled = true;
            foreach (ApplicationBarMenuItem mnu in ApplicationBar.MenuItems)
            {
                mnu.IsEnabled = true;
            }
            foreach (ApplicationBarIconButton btn in ApplicationBar.Buttons)
            {
                btn.IsEnabled = true;
            }
        }
        private void updateShakerState()
        {
            Point canvasOffset = Application.Current.RootVisual.TransformToVisual(canvas).Transform(new Point(0, 0));

            App.currentShaker.shakeImage = (WriteableBitmap)this.shakeImage.Source;
            App.currentShaker.shakeImagePosition = new Point(Canvas.GetLeft(this.shakeImage), Canvas.GetTop(this.shakeImage));
            App.currentShaker.shakeObj = App.shakeObjects;
            foreach (ShakeObject obj in App.currentShaker.shakeObjects)
            {
                obj.location = new Point(obj.location.X - canvasOffset.X, obj.location.Y - canvasOffset.Y);

            }
            AppSettings settings = new AppSettings();
            App.currentShaker.DampingRatio = settings.DampingRatioSetting;
            App.currentShaker.Frequency = settings.FrequencySetting;
            App.currentShaker.GravityRatio = settings.GravityRatioSetting;

            App.currentShaker.DragStrength = settings.DragStrengthSetting;
            App.currentShaker.MergeOverlay = settings.MergeOverlaySetting;
            //CompositeTransform ct = new CompositeTransform();
            //ct.ScaleX = scaleTransform.ScaleX;
            //ct.ScaleY = scaleTransform.ScaleY;
            //ct.CenterX = scaleTransform.CenterX;
            //ct.CenterY = scaleTransform.CenterY;
            //ct.Rotation = rotateTransform.Angle;
            //ct.TranslateX = translateTransform.X - canvasOffset.X;
            //ct.TranslateY = translateTransform.Y - canvasOffset.Y;

            App.currentShaker.matrix = previousTransform.Matrix;

            App.currentShaker.thumbnail = ResizeImage((WriteableBitmap)this.shakeImage.Source, 173);
        }

        private WriteableBitmap ResizeImage(WriteableBitmap bmp, int targetSize)
        {
            System.Windows.Controls.Image img = new System.Windows.Controls.Image();
            img.Source = bmp;
            double scaleX = 1;
            double scaleY = 1;

            if (bmp.PixelHeight > targetSize)
                scaleY = (double)targetSize / bmp.PixelHeight;
            if (bmp.PixelWidth > targetSize)
                scaleX = (double)targetSize / bmp.PixelWidth;


            double scale = Math.Max(scaleY, scaleX);

            int newWidth = Convert.ToInt32(bmp.PixelWidth * scale);
            int newHeight = Convert.ToInt32(bmp.PixelHeight * scale);
            WriteableBitmap result = new WriteableBitmap(targetSize, targetSize);
            result.Render(img, new CompositeTransform() { ScaleX = scale, ScaleY = scale, TranslateX = -(newWidth - targetSize) / 2, TranslateY = -(newHeight - targetSize) / 2 });
            result.Invalidate();
            return result;
        }


        private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
        {
            ShowHelpPage();
        }

        private void ShowHelpPage()
        {
            App.NavigateTo(CurrentView.HelpScreen);
        }

        private void ApplicationBarMenuItem_Click_1(object sender, EventArgs e)
        {
            btnSave_Click(sender, e);
        }

        private void ApplicationBarMenuItem_Click_2(object sender, EventArgs e)
        {
            ShowSettingsPage();
        }
        private void ShowSettingsPage()
        {
            App.NavigateTo(CurrentView.SettingsScreen);
        }

        private void ApplicationBarMenuItem_Click_3(object sender, EventArgs e)
        {
            Save(true);
        }

        private void shakeImage_DoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            Point p = e.GetPosition(canvas);
            //shakeImage.TransformToVisual(canvas).Transform(p);
            UIAddObject(p);
        }

        private void Show_Completed(object sender, EventArgs e)
        {
            OnNavigatedTo();
        }

        //protected override void OnNavigatedTo(NavigationEventArgs e)
        public void OnNavigatedTo()
        {
            LoadShakeDesigner();
            Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
         
            UpdateTrialMenuButtons();
            foreach (ShakeObjectCtl obj in App.shakeObjects)
            {
                obj.MergeOverlay();
            }

            ReleaseLayout();
            ShowCanvas.Begin();
            //<!--<toolkit:GestureService.GestureListener>
            //        <toolkit:GestureListener 
            //            Tap="OnTap" Hold="OnHold"
            //            DragStarted="OnDragStarted" DragDelta="OnDragDelta" DragCompleted="OnDragCompleted"
            //            Flick="OnFlick"
            //            PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" PinchCompleted="OnPinchCompleted"/>
            //    </toolkit:GestureService.GestureListener>-->
            //gl = GestureService.GetGestureListener(shakeImage);
            //gl.DragStarted += new EventHandler<DragStartedGestureEventArgs>(OnDragStarted);
            //gl.DragDelta += new EventHandler<DragDeltaGestureEventArgs>(OnDragDelta);
            //gl.DragCompleted += new EventHandler<DragCompletedGestureEventArgs>(OnDragCompleted);
            //gl.PinchStarted += new EventHandler<PinchStartedGestureEventArgs>(OnPinchStarted);
            //gl.PinchDelta += new EventHandler<PinchGestureEventArgs>(OnPinchDelta);
            //gl.PinchCompleted += new EventHandler<PinchGestureEventArgs>(OnPinchCompleted);

            // System.Windows.Input.Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
        }
        //protected override void OnNavigatedFrom(NavigationEventArgs e)
        public void OnNavigatedFrom()
        {
            Touch.FrameReported -= new TouchFrameEventHandler(Touch_FrameReported);
            if (App.IsTrial)
            {
                //AdRotatorControl.Dispose();
            }// 
            //gl.DragStarted -= new EventHandler<DragStartedGestureEventArgs>(OnDragStarted);
            //gl.DragDelta -= new EventHandler<DragDeltaGestureEventArgs>(OnDragDelta);
            //gl.DragCompleted -= new EventHandler<DragCompletedGestureEventArgs>(OnDragCompleted);
            //gl.PinchStarted -= new EventHandler<PinchStartedGestureEventArgs>(OnPinchStarted);
            //gl.PinchDelta -= new EventHandler<PinchGestureEventArgs>(OnPinchDelta);
            //gl.PinchCompleted -= new EventHandler<PinchGestureEventArgs>(OnPinchCompleted);

            //gl = null;
            // System.Windows.Input.Touch.FrameReported -= Touch_FrameReported;
            SuspendLayout();
            HideCanvas.Begin();
        }

        private void Hide_Completed(object sender, EventArgs e)
        {
            OnNavigatedFrom();
        }

        public void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            if (popup != null && popup.IsOpen)
            {
                saveCallback("", true);
                e.Cancel = true;
                return;
            }
            else
            {
                GoBack();
                e.Cancel = true;
            }
        }
      

    }
}